/*
 * Copyright (c) 2018-2999 九五云信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 */

package com.yami.shop.user.api.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.app.dto.*;
import com.yami.shop.bean.app.param.OrderParam;
import com.yami.shop.bean.app.param.OrderShopParam;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.UserAddr;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.constants.OrderCacheNames;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.i18n.LanguageEnum;
import com.yami.shop.common.util.CacheManagerUtil;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.RedisUtil;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.*;
import com.yami.shop.user.comment.dto.ScoreOrderMergerDto;
import com.yami.shop.user.comment.service.ScoreOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Objects;


/**
 * 积分商城接口
 *
 * @author LHD
 * @date 2019-11-01 09:36:59
 */
@RestController
@AllArgsConstructor
@RequestMapping("/p/score" )
@Api(tags = "积分商品订单接口")
public class ScoreOrderController {


    private final MapperFacade mapperFacade;
    private final UserExtensionService userExtensionService;

    private final ProductService productService;
    private final ScoreOrderService scoreOrderService;
    private final CacheManagerUtil cacheManagerUtil;
    private final StringRedisTemplate stringRedisTemplate;
    private final SkuService skuService;
    private final UserAddrService userAddrService;
    private final BasketService basketService;
    private final UserService userService;
//    private final UserScoreRecordService scoreRecordService;




    @GetMapping("/prodScorePage")
    @ApiOperation(value = "积分商品列表", notes = "获取积分商城首页商品列表")
    @ApiImplicitParams({
    })
    public ResponseEntity<IPage<ProductDto>> prodScorePage(PageParam<ProductDto> page) {
        IPage<ProductDto> productDtoIPage = productService.pageByScore(page);
        return ResponseEntity.ok(productDtoIPage);
    }


    /**
     * 积分商品购买
     */
    @PostMapping("/confirm")
    @ApiOperation(value = "购买，生成订单信息", notes = "传入下单所需要的参数进行下单")
    public ResponseEntity<ScoreOrderMergerDto> confirm(@Valid @RequestBody OrderParam orderParam) {
        if(orderParam.getOrderItem().getProdCount() < 1){
            // 请至少选择一件商品!
            throw  new YamiShopBindException("yami.score.select.num");
        }
        String userId = SecurityUtils.getUser().getUserId();
        // 订单的地址信息
        UserAddr userAddr = userAddrService.getUserAddrByUserId(orderParam.getAddrId(), userId);
        UserAddrDto userAddrDto = mapperFacade.map(userAddr, UserAddrDto.class);
        // 获取用户提交的商品
        ShopCartItemDto shopCartItemDto = basketService.getShopCartItem(orderParam.getOrderItem());
        //拼接商品信息
        ProductItemDto productItemDto = mapperFacade.map(shopCartItemDto,ProductItemDto.class);
        if (Objects.isNull(shopCartItemDto)) {
            // 请选择您需要的商品进行购买
            throw new YamiShopBindException("yami.score.select.num.shop");
        }

        // 将要返回给前端的完整的订单信息
        ScoreOrderMergerDto scoreOrderMergerDto = new ScoreOrderMergerDto();
        scoreOrderMergerDto.setUserAddr(userAddrDto);
        scoreOrderMergerDto.setShopId(Constant.PLATFORM_SHOP_ID);
        double actualTotal = shopCartItemDto.getProductTotalAmount();
        int totalCount = orderParam.getOrderItem().getProdCount();
        scoreOrderMergerDto.setUserId(userId);
        scoreOrderMergerDto.setTotal(actualTotal);
        scoreOrderMergerDto.setActualTotal(actualTotal);
        productItemDto.setActualTotal(actualTotal);
        //积分订单直接设置积分支付
        scoreOrderMergerDto.setIsScorePay(1);
        scoreOrderMergerDto.setTotalCount(totalCount);
        scoreOrderMergerDto.setTransfee( 0.0);
        scoreOrderMergerDto.setProductItemDto(productItemDto);

        if (StrUtil.isBlank(orderParam.getUuid())) {
            orderParam.setUuid(IdUtil.simpleUUID());
        }


        // 防止重复提交
        stringRedisTemplate.opsForValue().set(OrderCacheNames.SCORE_ORDER_CONFIRM_UUID_KEY + OrderCacheNames.UNION  + userId, userId);
        // 保存订单计算结果缓存，省得重新计算 并且 用户确认的订单金额与提交的一致
        cacheManagerUtil.putCache(OrderCacheNames.SCORE_ORDER_CONFIRM_KEY, userId,scoreOrderMergerDto);

        scoreOrderMergerDto.setUuid(orderParam.getUuid());
        return ResponseEntity.ok(scoreOrderMergerDto);
    }

    /**
     * 立即购买  提交积分订单
     */
    @PostMapping("/submit")
    @ApiOperation(value = "提交订单，返回支付流水号", notes = "提交积分订单，用户开始进行支付")
    public ResponseEntity<OrderNumbersDto> submitOrders(@Valid @RequestBody OrderShopParam orderShopParam) {
        String userId = SecurityUtils.getUser().getUserId();

        // 防止重复、同时提交
        boolean cad = RedisUtil.cad(OrderCacheNames.SCORE_ORDER_CONFIRM_UUID_KEY + OrderCacheNames.UNION  + userId, userId);
        System.out.println(" is cad " + cad);
        if (!cad) {
            // 订单状态已经发生改变，请重新下单
            throw new YamiShopBindException("yami.order.status.check.change");
        }

        // 看看订单的标记有没有过期
        if (cacheManagerUtil.getCache(OrderCacheNames.SCORE_ORDER_CONFIRM_KEY,  userId) == null) {
            // 订单已过期，请重新下单
            throw new YamiShopBindException("yami.order.expired");
        }

        ScoreOrderMergerDto mergerOrder = cacheManagerUtil.getCache(OrderCacheNames.SCORE_ORDER_CONFIRM_KEY, userId);
        if (mergerOrder == null) {
            // 订单已过期，请重新下单
            throw new YamiShopBindException("yami.order.expired");
        }

        UserExtension user = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId,userId));
        if(user.getScore() == null){
            user.setScore(0);
        }
        ProductItemDto productItemDto = mergerOrder.getProductItemDto();
        if(productItemDto.getScorePrice() > user.getScore()) {
            // 用户积分不足
            throw new YamiShopBindException("yami.user.score.enough");
        }
        StringBuilder orderNumbers = new StringBuilder();
        mergerOrder.setRemarks(orderShopParam.getRemarks());
        Order scoreOrder = scoreOrderService.submit(userId,mergerOrder);
        orderNumbers.append(scoreOrder.getOrderNumber());
        // 移除缓存
        skuService.removeSkuCacheBySkuIdAndLang(mergerOrder.getProductItemDto().getSkuId(),mergerOrder.getProductItemDto().getProdId(), LanguageEnum.LANGUAGE_ZH_CN.getLang());
        skuService.removeSkuCacheBySkuIdAndLang(mergerOrder.getProductItemDto().getSkuId(),mergerOrder.getProductItemDto().getProdId(),LanguageEnum.LANGUAGE_EN.getLang());
        productService.removeProdCacheByProdId(mergerOrder.getProductItemDto().getProdId(),LanguageEnum.LANGUAGE_ZH_CN.getLang());
        productService.removeProdCacheByProdId(mergerOrder.getProductItemDto().getProdId(),LanguageEnum.LANGUAGE_EN.getLang());
        scoreOrderService.removeConfirmScoreOrderCache(userId);
        return ResponseEntity.ok(new OrderNumbersDto(orderNumbers.toString()));
    }

//    /**
//     * 分页查询
//     * @param page 分页对象
//     * @return 分页数据
//     */
//    @GetMapping("/info" )
//    @ApiOperation(value="获取用户积分", notes="返回用户的积分信息")
//    public ResponseEntity<IPage<UserScoreRecord>> getScoreRecord(PageParam<UserScoreRecord> page) {
//        String userId = SecurityUtils.getUser().getUserId();
//        IPage<UserScoreRecord> scoreRecord = scoreRecordService.page(page,new LambdaQueryWrapper<UserScoreRecord>()
//                .eq(UserScoreRecord::getIoType,1)
//                .eq(UserScoreRecord::getUserId,userId)
//                .orderByDesc(UserScoreRecord::getCreateTime));
//        return ResponseEntity.ok(scoreRecord);
//    }

}
